

package com.maoshi.shop.user.api.controller;

import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.maoshi.shop.bean.event.PayVipEvent;
import com.maoshi.shop.bean.model.UserExtension;
import com.maoshi.shop.bean.pay.PayInfoDto;
import com.maoshi.shop.common.exception.MaoshiShopBindException;
import com.maoshi.shop.security.api.util.SecurityUtils;
import com.maoshi.shop.service.PayManagerService;
import com.maoshi.shop.service.UserExtensionService;
import com.maoshi.shop.user.comment.model.UserLevel;
import com.maoshi.shop.user.comment.model.UserLevelLog;
import com.maoshi.shop.user.comment.param.PayUserLevelParam;
import com.maoshi.shop.user.comment.service.UserLevelLogService;
import com.maoshi.shop.user.comment.service.UserLevelService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.context.ApplicationContext;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author LHD on 2020/03/02.
 */
@Api(tags = "会员购买接口")
@RestController
@RequestMapping("/p/level")
@AllArgsConstructor
public class PayLevelController {

    /**
     * 会员信息
     */
    private final UserLevelService userLevelService;
    private final UserExtensionService userExtensionService;
    private final ApplicationContext applicationContext;
    private final Snowflake snowflake;
    private final UserLevelLogService userLevelLogService;
    private final PayManagerService payManagerService;
    /**
     * 会员支付接口
     */
    @PostMapping("/payLevel")
    @ApiOperation(value = "根据会员等级进行支付", notes = "根据会员等级进行支付")
    @SneakyThrows
    public ResponseEntity<?> payVip(HttpServletResponse httpResponse, @RequestBody PayUserLevelParam payCardParam) {
        String openId = SecurityUtils.getUser().getBizUserId();
        UserExtension userExtension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>()
                                            .eq(UserExtension::getUserId, SecurityUtils.getUser().getUserId()));
        UserLevel userLevel = userLevelService.getById(payCardParam.getId());

        //如果会员等级为空
        if(userLevel == null || !Objects.equals(userLevel.getLevelType(),1)) {
            throw new MaoshiShopBindException("会员等级不存在或当前等级不为付费会员等级！");
        }

        if(Objects.equals(userExtension.getLevelType(),1) && userExtension.getLevel() > userLevel.getLevel()){
            throw new MaoshiShopBindException("用户无法在会员期间购买低等级会员！");
        }

        if(userExtension.getGrowth() < userLevel.getNeedGrowth()){
            throw new MaoshiShopBindException("用户成长值不足，无法购买！");
        }

        // 使用雪花算法生成支付单号
        String payNo = String.valueOf(snowflake.nextId());
        Date now = new Date();
        //生成等级日志
        UserLevelLog userLevelLog = new UserLevelLog();
        userLevelLog.setGiftTime(now);
        userLevelLog.setCreateTime(now);
        userLevelLog.setLevel(userLevel.getLevel());
        userLevelLog.setState(0);
        userLevelLog.setPayNo(payNo);
        userLevelLog.setIsPayed(0);
        userLevelLog.setUserId(userExtension.getUserId());
        //插入一条等级日志
        userLevelLogService.save(userLevelLog);
        List<String> domainNames = new ArrayList<>();
        //发送事件获取域名
        applicationContext.publishEvent(new PayVipEvent(domainNames));


        PayInfoDto payInfo = new PayInfoDto();
        payInfo.setBody("会员等级购买");
        payInfo.setPayAmount(userLevel.getNeedAmount());
        payInfo.setPayNo(payNo);
        payInfo.setBizUserId(openId);
        payInfo.setPayType(payCardParam.getPayType());
        payInfo.setApiNoticeUrl("/notice/levelPay/levelPayCallback/" + payCardParam.getPayType());

        return payManagerService.doPay(httpResponse, payInfo);

//       //TODO 支付成功测试
//        userLevelService.paySuccess(payNo);
//        return ResponseEntity.ok().build();
    }

}
